(ns ClojureProject2.core)

(defn strIsNumeric? [s]
  (if-let [s (seq s)]
    (let [s (if (= (first s) \-) (next s) s)
          s (drop-while #(Character/isDigit %) s)
          s (if (= (first s) \.) (next s) s)
          s (drop-while #(Character/isDigit %) s)]
      (empty? s))))

(defn other [player] (case player :X :O :O :X :Blank))

(defn makeGrid [n] (repeat n (repeat n :Blank)))

(defn setPlace [grid [row col] mark] (assoc grid row (assoc (grid row) col mark)))

(defn getPlace [grid [row col]] ((grid row) col))

(defn isTaken? [grid place] (not= (getPlace grid place) :Blank))

(defn isFull? [grid] (not-any? (partial = :Blank) (flatten grid)))

(defn getRow [grid row] (grid row))

(defn getCol [grid col] (map (fn [row] (row col)) grid))

(defn getDiag1 [grid] (map (partial getPlace grid) (map vector [0 1 2] [0 1 2])))

(defn getDiag2 [grid] (map (partial getPlace grid) (map vector [0 1 2] [2 1 0])))

(defn isWinner? [grid player] (true? (or
    (every? (partial = player) (getDiag1 grid))
    (every? (partial = player) (getDiag2 grid))
    (some (fn [row] (every? (partial = player) (getRow grid row))) [0 1 2])
    (some (fn [col] (every? (partial = player) (getCol grid col))) [0 1 2])
)))

(defn getWinner [grid] (cond (isWinner? grid :X) :X (isWinner? grid :O) :O :else :Blank))

(defn hasWinner? [grid] (not= (getWinner grid) :Blank))

(defn readInt [accept?] 
           (let [i (read-line)]
             (if (and (strIsNumeric? i) (accept? (read-string i)))
               (read-string i)
               (readInt accept?))))
(comment (readInt (fn [x] (and (< x 3) (>= x 0)))))

(comment defn gameLoop [grid player] ())

(defn -main [& args] (print "World"))
